﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Linq;
using System.Diagnostics;
using System.Text;
using System.IO;
using USB2XXX;

namespace USB2XXX_GPIO_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            USB_DEVICE.DEVICE_INFO DevInfo = new USB_DEVICE.DEVICE_INFO();
            Int32[] DevHandles = new Int32[20];
            Int32 DevHandle = 0;
            byte state;
            Int32 DevNum, ret;
            string dllFilePath = "USB2XXX.dll";
            if (!File.Exists(dllFilePath))
            {
                Console.WriteLine("请先将USB2XXX.dll和libusb-1.0.dll文件复制到exe程序文件输出目录下!");
                Console.WriteLine("dll文件在‘usb2can_lin_pwm_example/sdk/libs/windows’目录下！");
                Console.WriteLine("程序是32位的就复制‘x86’目录下文件，程序是64位的就复制‘x86_64’目录下文件！");
                return;
            }
            //扫描查找设备，并将每个设备的唯一设备号存放到数组中，后面的函数需要用到
            DevNum = USB_DEVICE.USB_ScanDevice(DevHandles);
            if (DevNum <= 0)
            {
                Console.WriteLine("No device connected!");
                return;
            }
            else
            {
                Console.WriteLine("Have {0} device connected!", DevNum);
            }
            DevHandle = DevHandles[0];//获取第一个设备的设备号
            //打开设备，必须调用
            state = USB_DEVICE.USB_OpenDevice(DevHandle);
            if (state==0)
            {
                Console.WriteLine("Open device error!");
                return;
            }
            else
            {
                Console.WriteLine("Open device success!");
            }
            //获取固件信息，可以不调用
            StringBuilder FuncStr = new StringBuilder(256);
            state = USB_DEVICE.DEV_GetDeviceInfo(DevHandle, ref DevInfo, FuncStr);
            if (state==0)
            {
                Console.WriteLine("Get device infomation error!");
                return;
            }
            else
            {
                Console.WriteLine("Firmware Info:");
                Console.WriteLine("    Name:" + Encoding.Default.GetString(DevInfo.FirmwareName));
                Console.WriteLine("    Build Date:" + Encoding.Default.GetString(DevInfo.BuildDate));
                Console.WriteLine("    Firmware Version:v{0}.{1}.{2}", (DevInfo.FirmwareVersion >> 24) & 0xFF, (DevInfo.FirmwareVersion >> 16) & 0xFF, DevInfo.FirmwareVersion & 0xFFFF);
                Console.WriteLine("    Hardware Version:v{0}.{1}.{2}", (DevInfo.HardwareVersion >> 24) & 0xFF, (DevInfo.HardwareVersion >> 16) & 0xFF, DevInfo.HardwareVersion & 0xFFFF);
                Console.WriteLine("    Functions:" + DevInfo.Functions.ToString("X8"));
                Console.WriteLine("    Functions String:" + FuncStr);
            }
            //对于UTA0504产品的GPIO Mask定义，其他型号有所不同
            const UInt16 GPIO_PIN_LIN1 =  0x0001;
            const UInt16 GPIO_PIN_LIN2  = 0x0002;
            const UInt16 GPIO_PIN_LIN3  = 0x0004;
            const UInt16 GPIO_PIN_LIN4  = 0x0008;
            const UInt16 GPIO_PIN_DO0   = 0x0010;
            const UInt16 GPIO_PIN_DO1   = 0x0020;
            const UInt16 GPIO_PIN_DI0   = 0x0040;
            const UInt16 GPIO_PIN_DI1   = 0x0080;
            const UInt16 GPIO_PIN_DI2   = 0x0100;
            const UInt16 GPIO_PIN_DI3 = 0x0200;
            //初始化DI引脚
            ret = USB2GPIO.GPIO_SetInput(DevHandle, GPIO_PIN_DI0 | GPIO_PIN_DI1 | GPIO_PIN_DI2 | GPIO_PIN_DI3,2);
            if (ret != USB2GPIO.GPIO_SUCCESS)
            {
                Console.WriteLine("Init gpio error!");
                return;
            }
            //初始化DO引脚
            ret = USB2GPIO.GPIO_SetOutput(DevHandle, GPIO_PIN_DO0 | GPIO_PIN_DO1, 2);
            if (ret != USB2GPIO.GPIO_SUCCESS)
            {
                Console.WriteLine("Init gpio error!");
                return;
            }
            //读取DI引脚状态
            UInt32[] PinValue = new UInt32[1];
            ret = USB2GPIO.GPIO_Read(DevHandle, GPIO_PIN_DI0 | GPIO_PIN_DI1 | GPIO_PIN_DI2 | GPIO_PIN_DI3, PinValue);
            if (ret != USB2GPIO.GPIO_SUCCESS)
            {
                Console.WriteLine("read gpio error!");
                return;
            }
            else
            {
                Console.WriteLine("GPIO_PIN_DI0 = " + (PinValue[0] & GPIO_PIN_DI0).ToString("X4"));
                Console.WriteLine("GPIO_PIN_DI1 = " + (PinValue[0] & GPIO_PIN_DI1).ToString("X4"));
                Console.WriteLine("GPIO_PIN_DI2 = " + (PinValue[0] & GPIO_PIN_DI2).ToString("X4"));
                Console.WriteLine("GPIO_PIN_DI3 = " + (PinValue[0] & GPIO_PIN_DI3).ToString("X4"));
            }
            //控制DO输出
            for (int i = 0; i < 10; i++)
            {
                ret = USB2GPIO.GPIO_Write(DevHandle, GPIO_PIN_DO0 | GPIO_PIN_DO1, 0);
                System.Threading.Thread.Sleep(10);
                ret = USB2GPIO.GPIO_Write(DevHandle, GPIO_PIN_DO0 | GPIO_PIN_DO1, 0xFFFF);
                System.Threading.Thread.Sleep(10);
            }
            Console.WriteLine("GPIO Test End!");
        }
    }
}
